﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ForrajeriaDB; //ESTE USING VA EN TODOS LOS ELEMENTOS DE ESTA CAPA
using System.Data;
using System.Data.SqlClient;

namespace ForrajeriaDAL
{
    public class EmpleadoDAL : AccesoDAL, InterfazDAL<EmpleadoMO>
    {
        #region VARIABLES PARA STORED QUE MANEJA EL OBJETO DE DAL

        private static string insert = "Empleado_INSERT";
        private static string delete = "Empleado_DELETE";
        private static string update = "Empleado_UPDATE";
        private static string all = "Empleado_GetALL";
        private static string getXID = "Empleado_GetByID";
        private static string allRegistrar = "Empleado_GetALLRegistrar";
        #endregion

        private SqlCommand cmd; //var de comando sql

        #region "Singleton"

        private static EmpleadoDAL instance;

        private EmpleadoDAL()
            : base()
        {

        }


        public static EmpleadoDAL Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new EmpleadoDAL();
                }
                return instance;
            }
        }

        #endregion

        public List<EmpleadoMO> getByFilters(string nombreLike, string apellidoLike, int? localidad, int? nroDoc)
        {
            List<EmpleadoMO> lista = new List<EmpleadoMO>();
            
            SqlCommand cmd = new SqlCommand(getCadena(), getConexion());

            string sql = "SELECT Empleado.codigo, Empleado.nombre, Empleado.apellido, Empleado.telefono, Empleado.tipoDocumento, Empleado.nroDocumento, Empleado.codigoUsuario, Empleado.estado, Empleado.calle, Empleado.nro, Empleado.piso, Empleado.dpto, Empleado.id_localidad, Localidad.nombre as NombreLocalidad FROM Empleado, Localidad WHERE Empleado.id_localidad=Localidad.id_localidad";
            if(!string.IsNullOrEmpty(nombreLike))
            {
                sql += " AND Empleado.nombre=@nombre";//'%%'";
                cmd.Parameters.AddWithValue("@nombre", nombreLike.ToString());
            }
            if (!string.IsNullOrEmpty(apellidoLike))
            {
                sql += " AND Empleado.apellido = @apellido";
                cmd.Parameters.AddWithValue("@apellido", apellidoLike.ToString());
            }
            if (localidad != null)
            {
                sql += " AND Empleado.id_localidad = @localidad";
                cmd.Parameters.AddWithValue("@localidad", localidad.Value);
            }
            if (nroDoc != null) 
            {
                sql += " AND Empleado.nroDocumento = @nroDoc";
                cmd.Parameters.AddWithValue("@nroDoc", nroDoc.Value);
            }

            cmd.CommandType = CommandType.Text;
            cmd.CommandText = sql;

            try
            {
                opencon();
                SqlDataReader dr = cmd.ExecuteReader();

                while(dr.Read())
                {
                    EmpleadoMO emp = new EmpleadoMO();
                    emp.Codigo = int.Parse(dr["Codigo"].ToString());
                    if (dr["Nombre"] != DBNull.Value)
                        emp.Nombre = dr["Nombre"].ToString();
                    if (dr["Apellido"] != DBNull.Value)
                        emp.Apellido = dr["Apellido"].ToString();
                    if (dr["Telefono"] != DBNull.Value)
                        emp.Telefono = dr["Telefono"].ToString();
                    if (dr["TipoDocumento"] != DBNull.Value)
                        emp.TipoDocumento = int.Parse(dr["TipoDocumento"].ToString());
                    if (dr["NroDocumento"] != DBNull.Value)
                        emp.NroDocumento = int.Parse(dr["NroDocumento"].ToString());
                    if (dr["CodigoUsuario"] != DBNull.Value)
                        emp.CodigoUsuario = int.Parse(dr["CodigoUsuario"].ToString());
                    if (dr["NombreLocalidad"] != DBNull.Value)
                        emp.Estado = dr["NombreLocalidad"].ToString();
                    if (dr["Calle"] != DBNull.Value)
                        emp.Calle = dr["Calle"].ToString();
                    if (dr["Nro"] != DBNull.Value)
                        emp.NroCalle = int.Parse(dr["Nro"].ToString());
                    if (dr["Piso"] != DBNull.Value)
                        emp.Piso = dr["Piso"].ToString();
                    if (dr["Dpto"] != DBNull.Value)
                        emp.Dpto = dr["Dpto"].ToString();
                    if (dr["Id_Localidad"] != DBNull.Value)
                        emp.Localidad = int.Parse(dr["Id_Localidad"].ToString());
                    //if (dr["NombreLocalidad"] != DBNull.Value)
                    //    emp.NombreLocalidad = dr["NombreLocalidad"].ToString();

                    lista.Add(emp);
                }
            }
            catch (Exception ex)
            {
                
                throw ex;
            }
            finally
            {
                closecon();
            }
            return lista;

        }
        public List<EmpleadoInforme> getInforme(float? montoVendido, int? provincia, int? localidad) //Recibe como parametros los filtros, y devuelve en base a eso los empleados, sus localidades y provincias y el monto total vendido
        {
            List<EmpleadoInforme> lista = new List<EmpleadoInforme>();
            //EmpleadoInforme empInf = new EmpleadoInforme();
            string sql = "SELECT Empleado.codigo as Codigo, Empleado.nombre as Nombre, Empleado.apellido as Apellido, Empleado.id_localidad as Localidad, Localidad.nombre as LocalidadNom, Localidad.codigoProvincia as Provincia, Provincia.Nombre as ProvinciaNom, SUM(Factura.totalFactura) as montoTotal";
            sql += " FROM Empleado, Localidad, Provincia, Factura";
            sql += " WHERE Empleado.id_localidad = Localidad.id_localidad AND Localidad.codigoProvincia=Provincia.codigoProvincia AND Empleado.codigo=Factura.codigoEmpleado";
            if(localidad!=null) sql += " AND Empleado.id_localidad = @localidad";
            if (provincia != null) sql += " AND Localidad.codigoProvincia = @provincia";
            sql += " GROUP BY Empleado.codigo, Empleado.nombre, Empleado.apellido, Empleado.id_localidad, Localidad.nombre, Localidad.codigoProvincia, Provincia.Nombre";
            if (montoVendido != null) sql += " HAVING SUM(Factura.totalFactura) >= @montoVendido";
            sql += " ORDER BY montoTotal desc";

            SqlCommand cmd = new SqlCommand(getCadena(), getConexion());

            cmd.CommandText = sql;
            if (localidad != null) cmd.Parameters.AddWithValue("@localidad", localidad.Value);
            if (provincia != null) cmd.Parameters.AddWithValue("@provincia", provincia.Value); 
            if (montoVendido != null) cmd.Parameters.AddWithValue("@montoVendido", montoVendido.Value);

            try
            {
                opencon();
                SqlDataReader dr = cmd.ExecuteReader();

                while (dr.Read())
                {
                    EmpleadoInforme empInf = new EmpleadoInforme();
                    empInf.Codigo = int.Parse(dr["Codigo"].ToString());
                    empInf.Nombre = dr["Nombre"].ToString();
                    empInf.Apellido = dr["Apellido"].ToString();

                    if (dr["Localidad"] != DBNull.Value)
                        empInf.Localidad = int.Parse(dr["Localidad"].ToString());
                    empInf.LocalidadNom = dr["LocalidadNom"].ToString();
                    empInf.Provincia = int.Parse(dr["Provincia"].ToString());
                    empInf.ProvinciaNom = dr["ProvinciaNom"].ToString();
                    empInf.MontoVendido = float.Parse(dr["montoTotal"].ToString());

                    lista.Add(empInf);
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                closecon();
            }

            

            return lista;
        }

       

        public List<EmpleadoMO> GetAll()
        {
            List<EmpleadoMO> lista = new List<EmpleadoMO>();
            SqlCommand cmd = new SqlCommand(getCadena(), getConexion());
            string sql = "SELECT Empleado.codigo, Empleado.nombre, Empleado.apellido, Empleado.telefono, Empleado.tipoDocumento, Empleado.nroDocumento, Empleado.codigoUsuario, Empleado.estado, Empleado.calle, Empleado.nro, Empleado.piso, Empleado.dpto, Empleado.id_localidad, Localidad.nombre as NombreLocalidad FROM Empleado, Localidad WHERE Empleado.id_localidad=Localidad.id_localidad";
            try
            {
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = sql;
                opencon();


                SqlDataReader dr = cmd.ExecuteReader();

                while (dr.Read())
                {
                    EmpleadoMO emp = new EmpleadoMO();
                    emp.Codigo = int.Parse(dr["Codigo"].ToString());
                    if (dr["Nombre"] != DBNull.Value)
                        emp.Nombre = dr["Nombre"].ToString();

                    if (dr["Apellido"] != DBNull.Value)
                        emp.Apellido = dr["Apellido"].ToString();
                    if (dr["Telefono"] != DBNull.Value)
                        emp.Telefono = dr["Telefono"].ToString();
                    if (dr["TipoDocumento"] != DBNull.Value)
                        emp.TipoDocumento = int.Parse(dr["TipoDocumento"].ToString());
                    if (dr["NroDocumento"] != DBNull.Value)
                        emp.NroDocumento = int.Parse(dr["NroDocumento"].ToString());
                    if (dr["CodigoUsuario"] != DBNull.Value)
                        emp.CodigoUsuario = int.Parse(dr["CodigoUsuario"].ToString());
                    if (dr["NombreLocalidad"] != DBNull.Value)
                        emp.Estado = dr["NombreLocalidad"].ToString();
                    if (dr["Calle"] != DBNull.Value)
                        emp.Calle = dr["Calle"].ToString();
                    if (dr["Nro"] != DBNull.Value)
                        emp.NroCalle = int.Parse(dr["Nro"].ToString());
                    if (dr["Piso"] != DBNull.Value)
                        emp.Piso = dr["Piso"].ToString();
                    if (dr["Dpto"] != DBNull.Value)
                        emp.Dpto = dr["Dpto"].ToString();
                    if (dr["Id_Localidad"] != DBNull.Value)
                        emp.Localidad = int.Parse(dr["Id_Localidad"].ToString());
                    //if (dr["NombreLocalidad"] != DBNull.Value)
                    //    emp.NombreLocalidad = dr["NombreLocalidad"].ToString();

                    lista.Add(emp);
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                closecon();
            }

            return lista;
        }

        public EmpleadoMO obtenerEmpleado(int cod)
        {
            EmpleadoMO emp = new EmpleadoMO();
            emp.Codigo = cod;
            SqlCommand cmd = new SqlCommand(getCadena(), getConexion());

            string sql = "SELECT codigo, nombre, apellido, telefono, tipoDocumento, nroDocumento, codigoUsuario, estado, calle, nro, piso, dpto, id_localidad from Empleado WHERE codigo = @Codigo";

            cmd.Parameters.AddWithValue("@Codigo", emp.Codigo);

            cmd.CommandText = sql;

            try
            {
                opencon();
                SqlDataReader dr = cmd.ExecuteReader();

                while(dr.Read())
                {
                    emp.Codigo = int.Parse(dr["codigo"].ToString());
                    emp.Nombre = dr["nombre"].ToString();
                    emp.Apellido = dr["apellido"].ToString();
                    emp.Telefono = dr["telefono"].ToString();
                    emp.TipoDocumento = int.Parse(dr["tipoDocumento"].ToString());
                    emp.NroDocumento = int.Parse(dr["nroDocumento"].ToString());
                    if (dr["codigoUsuario"] != DBNull.Value)
                        emp.CodigoUsuario = int.Parse(dr["codigoUsuario"].ToString());
                    emp.Estado = dr["estado"].ToString();
                    emp.Calle = dr["calle"].ToString();
                    emp.NroCalle = int.Parse(dr["nro"].ToString());
                    emp.Piso = dr["piso"].ToString();
                    emp.Dpto = dr["dpto"].ToString();
                    if (dr["id_localidad"] != DBNull.Value)
                        emp.Localidad = int.Parse(dr["id_localidad"].ToString());
                }

            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                closecon();
            }

            return emp;
        }

        public void  eliminar(EmpleadoMO emp)
        {
            SqlCommand cmd = new SqlCommand(getCadena(), getConexion());

            try
            {
                string sql = "DELETE from Empleado where codigo = @codigo";
                cmd.CommandText = sql;
                cmd.Parameters.AddWithValue("@codigo", emp.Codigo);
                opencon();
                cmd.ExecuteNonQuery();

            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                closecon();
            }

        }

        //public void actualizar(int? codEmpleado, string nombre, string apellido, string telefono, int tipoDoc, int nroDoc, int codUsuario, string estado, string calle, int nroCalle, string piso, string depto, int localidad)
        public void actualizar(EmpleadoMO emp)
        {
            SqlCommand cmd = new SqlCommand(getCadena(), getConexion());
            string sql = "";
            if (emp.Codigo == -1)
            {
                sql = "INSERT into Empleado ";
                sql += "(nombre, apellido, telefono, tipoDocumento, nroDocumento, calle, nro, piso, dpto, id_localidad)";
                sql += "values (@nombre, @apellido, @telefono, @tipoDoc, @nroDoc, @calle, @nroCalle, @piso, @depto, @localidad)";
            }
            else
            {
                sql = "UPDATE Empleado set nombre=@nombre, apellido=@apellido, telefono=@telefono, tipoDocumento=@tipoDoc, nroDocumento=@nroDoc, calle=@calle, nro=@nroCalle, piso=@piso, dpto=@depto, id_localidad=@localidad WHERE codigo = @codEmpleado";
                cmd.Parameters.AddWithValue("@codEmpleado", emp.Codigo);
            }

            cmd.CommandText = sql;

            cmd.Parameters.AddWithValue("@nombre", emp.Nombre);
            cmd.Parameters.AddWithValue("@apellido", emp.Apellido);
            cmd.Parameters.AddWithValue("@telefono", emp.Telefono);
            cmd.Parameters.AddWithValue("@tipoDoc", emp.TipoDocumento);
            cmd.Parameters.AddWithValue("@nroDoc", emp.NroDocumento);
            //cmd.Parameters.AddWithValue("@codUsuario", emp.CodigoUsuario);
            //cmd.Parameters.AddWithValue("@estado", emp.Estado);
            cmd.Parameters.AddWithValue("@calle", emp.Calle);
            cmd.Parameters.AddWithValue("@nroCalle", emp.NroCalle);
            cmd.Parameters.AddWithValue("@piso", emp.Piso);
            cmd.Parameters.AddWithValue("@depto", emp.Dpto);
            cmd.Parameters.AddWithValue("@localidad", emp.Localidad);

            try
            {
                opencon();
                cmd.ExecuteNonQuery();

                if (emp.Codigo==-1)
                {
                    cmd.CommandText = "select @@identity codigo";
                    emp.Codigo = int.Parse(cmd.ExecuteScalar().ToString());
                }

            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                closecon();
            }

        }



        

        public void Adicionar(EmpleadoMO item)
        {
           
            item.Codigo = getCodigoInsert("Empleado", "codigo");

            try
            {
                cmd = new SqlCommand(insert, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add(new SqlParameter("@codigo",item.Codigo));
                cmd.Parameters.Add(new SqlParameter("@nombre", item.Nombre));
                cmd.Parameters.Add(new SqlParameter("@apellido",  item.Apellido));
                cmd.Parameters.Add(new SqlParameter("@teléfono", item.Telefono));
                cmd.Parameters.Add(new SqlParameter("@tipoDocumento", item.TipoDocumento));
                cmd.Parameters.Add(new SqlParameter("@nroDocumento",  item.NroDocumento));
                cmd.Parameters.Add(new SqlParameter("@codigoUsuario", item.CodigoUsuario));
                cmd.Parameters.Add(new SqlParameter("@estado", "A"));
                cmd.Parameters.Add(new SqlParameter("@calle",item.Calle));
                cmd.Parameters.Add(new SqlParameter("@nro", item.NroCalle));
                cmd.Parameters.Add(new SqlParameter("@piso",  item.Piso));
                cmd.Parameters.Add(new SqlParameter("@dpto",  item.Dpto));
                cmd.Parameters.Add(new SqlParameter("@id_localidad",  item.Localidad));





                opencon();
                cmd.ExecuteNonQuery();
                closecon();

            }
            catch (Exception ex)
            {
                closecon();
                throw ex;
            }
            
        }

        public void Eliminar(EmpleadoMO item)
        {
            throw new NotImplementedException();
           
        }

        public void Actualizar(EmpleadoMO nuevoItem, EmpleadoMO origItem)
        {
            throw new NotImplementedException();
            
        }
       

        public DataTable reporteEmpleadoMasVentas(DateTime fecha, string ordena = "", string dire = "")
        {
            string sql = "";
            sql = "select top 1 t.codigo as 'Codigo',MAX(t.total) as 'Total',CONVERT(varchar(10) ,t.fecha,103) as 'Fecha', t.nombre 'Nombre', t.apellido as 'Apellido',t.teléfono as 'Telefono',t.tipoDocumento as 'Tipo de Documento',t.nroDocumento as 'Numero de Documento',t.direccion as 'Direccion' "
                        + "from ( "
                        + " SELECT f.codigoEmpleado as codigo,SUM(f.totalFactura) as total, f.fecha , e.nombre, e.apellido,e.teléfono,d.tipoDocumento,e.nroDocumento,((convert(varchar(50),isnull(e.calle,'-')))+' '+(convert(varchar(50),isnull(e.nro,'-')))+' '+(convert(varchar(50),isnull(e.piso,'')))+' '+(convert(varchar(50),isnull(e.dpto,'')))) as direccion, e.estado "
                        + " FROM Empleado e "
                        + " left join TipoDocumento d on e.tipoDocumento = d.codigo "
                        + " inner join Factura f on e.codigo = f.codigoEmpleado "
                        + " group by e.estado,f.fecha ,f.codigoEmpleado,e.nombre, e.apellido,e.teléfono,d.tipoDocumento,e.nroDocumento,((convert(varchar(50),isnull(e.calle,'-')))+' '+(convert(varchar(50),isnull(e.nro,'-')))+' '+(convert(varchar(50),isnull(e.piso,'')))+' '+(convert(varchar(50),isnull(e.dpto,'')))) ) t "
                        + " group by t.codigo,t.fecha,t.nombre,t.apellido,t.nroDocumento,t.tipoDocumento,t.direccion,t.teléfono, t.estado "
                        + " having t.estado = 'A' ";
                        
            try
            {
                DataTable dt = new DataTable();

                SqlCommand cmd = new SqlCommand();
                
                if (fecha != null)
                {
                    
                    sql += " and  t.fecha = @fecha";
                    cmd.Parameters.Add("@fecha", SqlDbType.DateTime).Value = fecha;
                }

                if (ordena != "")
                {

                    sql += " Order by " + ordena ;

                }
                if (dire != "")
                    sql += " " + dire;
                
                
                cmd.Connection =(getConexion());
                
                cmd.CommandText = sql;
                cmd.CommandType = CommandType.Text;
                SqlDataAdapter da = new SqlDataAdapter(cmd);

                opencon();
                da.Fill(dt);
                closecon();
                return dt;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                closecon();
            }
        
        }
        public EmpleadoMO getByID(int codigo)
        {

            try
            {
                cmd = new SqlCommand(getXID, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add(new SqlParameter("@id", codigo));

                opencon();
                SqlDataReader reader = cmd.ExecuteReader();
                EmpleadoMO aux = new EmpleadoMO();
                if (reader.Read())
                {

                    aux.Codigo = int.Parse(reader["codigo"].ToString());

                    if (reader["apellido"].ToString() != null)
                    { aux.Apellido = reader["apellido"].ToString(); }
                    else { aux.Apellido = ""; }

                    if (reader["nombre"].ToString() != null)
                    { aux.Nombre = reader["nombre"].ToString(); }
                    else { aux.Nombre = ""; }



                    if (reader["telefono"].ToString() != null)
                    { aux.Telefono = reader["telefono"].ToString(); }
                    else { aux.Telefono = ""; }

                    aux.TipoDocumento = int.Parse(reader["tipoDocumento"].ToString());

                    aux.NroDocumento = int.Parse(reader["nroDocumento"].ToString());

                    aux.CodigoUsuario = int.Parse(reader["nroDocumento"].ToString());


                    aux.Estado = reader["estado"].ToString();


                    aux.Calle = reader["calle"].ToString();


                    if (reader["nroCalle"].ToString() != null)
                    { aux.NroCalle = int.Parse(reader["nroCalle"].ToString()); }
                    else { aux.Calle = "0"; }

                    if (reader["piso"].ToString() != null)
                    { aux.Piso = reader["piso"].ToString(); }
                    else { aux.Piso = ""; }

                    if (reader["dpto"].ToString() != null)
                    { aux.Dpto = reader["dpto"].ToString(); }
                    else { aux.Dpto = ""; }


                    aux.Localidad = int.Parse(reader["id_localidad"].ToString());

                }

                reader.Close();
                closecon();
                return aux;
            }

            catch (SqlException ex)
            {
                closecon();
                throw new Exception("Error de Tipo SQL SERVER: " + ex.Message);
            }
            catch (Exception ex)
            {
                closecon();
                throw new Exception("Error Desconocido: " + ex.Message);
            }


        }


        public List<EmpleadoMO> getAllRegistrar()
        {
            
            SqlDataReader reader = null;
            List<EmpleadoMO> lista = new List<EmpleadoMO>();
            try
            {
                cmd = new SqlCommand(allRegistrar, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;
                opencon();
                reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    EmpleadoMO aux = new EmpleadoMO();
                    //****************************Formar objeto aux**********************
                    aux.Codigo = int.Parse(reader["codigo"].ToString());

                    if (reader["apellido"].ToString() != null)
                    { aux.Apellido = reader["apellido"].ToString(); }
                    else { aux.Apellido = ""; }

                    if (reader["nombre"].ToString() != null)
                    { aux.Nombre = reader["nombre"].ToString(); }
                    else { aux.Nombre = ""; }



                    if (reader["telefono"].ToString() != null)
                    { aux.Telefono = reader["telefono"].ToString(); }
                    else { aux.Telefono = ""; }

                    aux.TipoDocumento = int.Parse(reader["tipoDocumento"].ToString());

                    aux.NroDocumento = int.Parse(reader["nroDocumento"].ToString());

                    aux.CodigoUsuario = int.Parse(reader["nroDocumento"].ToString());


                    aux.Estado = reader["estado"].ToString();


                    aux.Calle = reader["calle"].ToString();


                    if (reader["nroCalle"].ToString() != null)
                    { aux.NroCalle = int.Parse(reader["nroCalle"].ToString()); }
                    else { aux.Calle = "0"; }

                    if (reader["piso"].ToString() != null)
                    { aux.Piso = reader["piso"].ToString(); }
                    else { aux.Piso = ""; }

                    if (reader["dpto"].ToString() != null)
                    { aux.Dpto = reader["dpto"].ToString(); }
                    else { aux.Dpto = ""; }


                    aux.Localidad = int.Parse(reader["id_localidad"].ToString());
                   


                    //************************Fin Formar objeto aux*********************
                    lista.Add(aux);
                    aux = null;
                }
                return lista;
            }
            catch (Exception ex)
            {
                throw ex; //en caso que no pueda leer desde la base de datos tira el hacia la siguiente capa 
            }
            finally //finalmente cierro el reader que use para traer la consulta esto es importante ya que por alguna razon podria quedar abierto generando una conexion sin uso en la bd que estaria todo el tiempo abierta
            {
                closeReader(reader); //cierro el reader
                closecon();// cierra conexion

            }
        }



    }


}
